package com.harmonyos.samples.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.harmonyos.samples.bean.cache.CacheBean;
import com.harmonyos.samples.bean.cache.CacheDetail;
import com.harmonyos.samples.bean.cache.CacheType;
import com.harmonyos.samples.constants.Constants;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class CacheUtils {
    private static final String CASE_PLUGIN_CACHE_PATH = InsertUtils.getCacheDirectory() + "/cache";

    private List<CacheBean> cacheList = new ArrayList<>();

    private Path cacheFilePath;

    private ObjectMapper mapper;

    private Date date;

    private static volatile CacheUtils instance;

    private CacheUtils() {
        try {
            mapper = new ObjectMapper();
            date = new Date();
            File cacheFile = new File(CASE_PLUGIN_CACHE_PATH);
            if (!cacheFile.exists()) {
                cacheFile.createNewFile();
            }
            cacheFilePath = cacheFile.toPath();
            String cacheJson = Files.readString(cacheFilePath);
            if (cacheJson != null && !cacheJson.isEmpty()) {
                cacheList = mapper.readValue(cacheJson, new TypeReference<>() {
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static CacheUtils getInstance() {
        synchronized (CacheUtils.class) {
            if (instance == null) {
                synchronized (CacheUtils.class) {
                    if (instance == null) {
                        instance = new CacheUtils();
                    }
                }
            }
        }
        return instance;
    }

    private List<CacheBean> readCache() {
        return cacheList;
    }

    public void add(CacheType cacheType, String name) {
        boolean cacheTypeExist = false;
        for(CacheBean cacheBean : cacheList) {
            if (cacheBean.getType() == cacheType.getValue()) {
                cacheTypeExist = true;
                boolean cacheExist = false;
                for (CacheDetail detail : cacheBean.getDetails()) {
                    if (detail.getName().equals(name)) {
                        cacheExist = true;
                        update(cacheType, name);
                        break;
                    }
                }
                if (!cacheExist) {
                    CacheDetail detail = new CacheDetail();
                    detail.setName(name);
                    detail.setUpdateTime(date.getTime());
                    cacheBean.getDetails().add(detail);
                }
                break;
            }
        }
        if (!cacheTypeExist) {
            CacheBean cacheBean = new CacheBean();
            cacheBean.setType(cacheType.getValue());
            List<CacheDetail> details = new ArrayList<>();
            CacheDetail detail = new CacheDetail();
            detail.setName(name);
            detail.setUpdateTime(date.getTime());
            details.add(detail);
            cacheBean.setDetails(details);
            cacheList.add(cacheBean);
            updateCache();
        }
    }

    public boolean update(CacheType cacheType, String name) {
        for(CacheBean cacheBean : cacheList) {
            if (cacheBean.getType() == cacheType.getValue()) {
                List<CacheDetail> details = cacheBean.getDetails();
                for(CacheDetail detail : details) {
                    if (detail.getName().equals(name)) {
                        long dateTime = date.getTime();
                        if (dateTime - detail.getUpdateTime() > Constants.ONE_DAY) {
                            detail.setUpdateTime(dateTime);
                            updateCache();
                            return true;
                        } else {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    private void updateCache() {
        try {
            Files.writeString(cacheFilePath, mapper.writeValueAsString(cacheList));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
